package cn.tedu.travelsystem.base.service;

import cn.tedu.travelsystem.hotel.mapper.HotelMapper;
import cn.tedu.travelsystem.hotel.pojo.entity.Hotel;
import cn.tedu.travelsystem.scenicSpot.mapper.ScenicSpotMapper;
import cn.tedu.travelsystem.scenicSpot.pojo.entity.ScenicSpot;
import cn.tedu.travelsystem.transport.mapper.TransportMapper;
import cn.tedu.travelsystem.transport.pojo.entity.Transport;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class ReservationService {

    private final HotelMapper hotelMapper;
    private final ScenicSpotMapper scenicSpotMapper;
    private final TransportMapper transportMapper;
    private final MonitoringService monitoringService;
    private final StringRedisTemplate redisTemplate;

    @Value("${mock.reserved.spot:90}")
    private int mockScenicReservations;

    @Value("${mock.available.transport:10}")
    private int mockTransportSeats;

    private static final long CACHE_TTL_MINUTES = 10;

    // ---------------------- 实时库存更新 ----------------------

    public void updateHotelInventory(Integer hotelId, int usedBeds) {
        int available = getIntFromCache("hotel:inventory:" + hotelId,
                hotelMapper.selectById(hotelId).getCurrent_inventory());
        int updated = available - usedBeds;
        cacheSet("hotel:inventory:" + hotelId, updated);
        log.info("✅ 酒店 [{}] 库存更新，剩余床位：{}", hotelId, updated);

        Hotel hotel = hotelMapper.selectById(hotelId);
        if (hotel != null) {
            monitoringService.checkHotelOverbook(hotel, updated);
        }
    }

    public void updateScenicReservations(Integer spotId, int newVisitors) {
        int current = getIntFromCache("scenicSpot:reservations:" + spotId, mockScenicReservations);
        int updated = current + newVisitors;
        cacheSet("scenicSpot:reservations:" + spotId, updated);
        log.info("✅ 景区 [{}] 预约更新，总预约：{}", spotId, updated);

        ScenicSpot spot = scenicSpotMapper.selectById(spotId);
        if (spot != null) {
            monitoringService.checkScenicOverbook(spot, updated);
        }
    }

    public void updateTransportSeats(Integer transportId, int usedSeats) {
        int available = getIntFromCache("transport:seats:" + transportId, mockTransportSeats);
        int updated = available - usedSeats;
        cacheSet("transport:seats:" + transportId, updated);
        log.info("✅ 交通 [{}] 座位更新，剩余座位：{}", transportId, updated);

        Transport transport = transportMapper.selectById(transportId);
        if (transport != null) {
            monitoringService.checkTransportOverbook(transport, updated);
        }
    }

    // ---------------------- 缓存通用方法 ----------------------

    private int getIntFromCache(String key, int defaultValue) {
        String cached = redisTemplate.opsForValue().get(key);
        try {
            return cached != null ? Integer.parseInt(cached) : defaultValue;
        } catch (NumberFormatException e) {
            log.warn("⚠️ 无效缓存值 [{}]: {}", key, cached);
            return defaultValue;
        }
    }

    private void cacheSet(String key, int value) {
        redisTemplate.opsForValue().set(key, String.valueOf(value), CACHE_TTL_MINUTES, TimeUnit.MINUTES);
    }
}
